/*
 * @Author: 无聊 7989314+Hwz1997@user.noreply.gitee.com
 * @Date: 2025-07-01 12:01:14
 * @LastEditors: 无聊 7989314+Hwz1997@user.noreply.gitee.com
 * @LastEditTime: 2025-09-25 09:41:33
 * @FilePath: \keep_motion_api\models\sport\trainingPlan.model.js
 * @Description: 这是默认设置,请设置`customMade`, 打开koroFileHeader查看配置 进行设置: https://github.com/OBKoro1/koro1FileHeader/wiki/%E9%85%8D%E7%BD%AE
 */
const mongoose = require('mongoose');
const Schema = mongoose.Schema;
const { escapeRegex } = require('@/utils');

// 训练计划模型
const trainingPlanSchema = new Schema({
  name: { type: String, required: true },
  description: String,
  sport_types: [{
    type: Schema.Types.ObjectId, 
    ref: 'SportType'
  }],
  difficulty_level: String,
  daily_duration: Number,
  target_users: [String],
  is_recommended: Boolean,
  related_courses: [{
    type: Schema.Types.ObjectId,
    ref: 'Course'
  }]
});
trainingPlanSchema.statics.getTrainingPlans = async function (name, offset = 0, limit = 10) {
  try {
    const query = {};
    if(name){
      const escapedName = escapeRegex(name);
      query.name = { $regex: escapedName, $options: 'i' };
    }
    
    // 使用aggregate聚合管道一次性完成所有查询和数据处理
    const [result] = await this.aggregate([
      // 1. 匹配查询条件
      { $match: query },
      
      // 2. 关联查询sport_types数据
      { $lookup: {
        from: 'sporttypes', // 关联的集合名
        localField: 'sport_types', // 本地关联字段
        foreignField: '_id', // 关联集合的匹配字段
        as: 'sport_types_info' // 存储关联结果的字段名
      }},
      
      // 3. 关联查询related_courses数据
      { $lookup: {
        from: 'courses', // 关联的集合名
        localField: 'related_courses', // 本地关联字段
        foreignField: '_id', // 关联集合的匹配字段
        as: 'related_courses_info' // 存储关联结果的字段名
      }},
      
      // 4. 统计总数并添加到每个文档中（用于后续分页后仍能获取总条数）
      { $facet: {
        metadata: [{
          $count: 'total' // 统计符合条件的总文档数
        }],
        data: [
          // 投影需要的字段
          { $project: {
            _id: 1,
            name: 1,
            description: 1,
            difficulty_level: 1,
            daily_duration: 1,
            target_users: 1,
            is_recommended: 1,
            sport_types: 1, // 保留原始ID数组
            related_courses: 1, // 保留原始ID数组
            sport_types_info: 1, // 关联的详细信息
            related_courses_info: 1, // 关联的详细信息
            // 使用$map和$arrayElemAt创建sport_type_names数组
            sport_type_names: {
              $map: {
                input: '$sport_types_info',
                as: 'type',
                in: '$$type.name'
              }
            },
            // 使用$map和$arrayElemAt创建related_courses_titles数组
            related_courses_titles: {
              $map: {
                input: '$related_courses_info',
                as: 'course',
                in: '$$course.title'
              }
            }
          }},
          // 分页
          { $skip: Number(offset) },
          { $limit: Number(limit) }
        ]
      }},
      
      // 5. 整合结果
      { $unwind: '$metadata' },
      { $project: {
        rows: '$data',
        total: '$metadata.total'
      }}
    ]);
    
    // 处理没有结果的情况
    if (!result || !result.rows) {
      return { rows: [], total: 0 };
    }
    
    return result;
  } catch (error) {
    console.error('获取训练计划失败:', error);
    throw new Error('获取训练计划失败');
  }
};
trainingPlanSchema.statics.createTrainingPlans = async function (params) {
  try {
    const trainingPlan = new this(params);
    return await trainingPlan.save();
  } catch (error) {
    throw new Error('创建训练计划失败');
  }
}
trainingPlanSchema.statics.updateTrainingPlans = async function (id, params) {
  try {
    const trainingPlan = await this.findByIdAndUpdate(id, params, { new: true });
    if (!trainingPlan) throw new Error('训练计划不存在');
    return trainingPlan;
  } catch (error) {
    throw new Error('更新训练计划失败');
  }
}
trainingPlanSchema.statics.recommendTrainingPlan = async function (id, is_recommended) {
  try {
    const trainingPlan = await this.findByIdAndUpdate(id, { is_recommended }, { new: true });
    if (!trainingPlan) throw new Error('训练计划不存在');
    return trainingPlan;
  } catch (error) {
    throw new Error('更新训练计划推荐状态失败');
  }
}

module.exports = mongoose.model('TrainingPlan', trainingPlanSchema);